package entities;

import java.util.Vector;

import javax.microedition.khronos.opengles.GL10;

import utility.VecHelper;
import utility.vec2;

import collisionPrimitives.CRect;

import com.liquidcode.cellular.CAssetManager;
import com.liquidcode.cellular.CAttackManager;
import com.liquidcode.cellular.CCamera;
import com.liquidcode.cellular.CHealthBar;
import com.liquidcode.cellular.R;
import com.liquidcode.cellular.Texture;

import android.content.Context;
import android.content.res.AssetManager;

public class CPlayer extends CBaseObject {
	
	private int m_nType;
	private CAnimatedSprite m_sprite;
	private float m_fRotation = 0.0f;
	private float m_fSpeed = 4.0f;
	private float MOVEMENT_SPEED = 180.0f;
	private float MOVEMENT_REDUCTION_RATE = 0.01f;
	private float MOVEMENT_INCREASE_RATE = 0.03f;
	private boolean m_bMoving = false;
	private static CPlayer mInstance = null; // the singleton instance for the
	protected CRect m_rect;
	private int m_screenWidth; 
	private int m_screenHeight;
	private boolean m_bAttachCamera = true; 
	private boolean m_bAttachCameraX = false;
	private boolean m_bAttachCameraY = false;
	private float m_fScreenClampFactor = 1.0f;
	private CHealthBar m_healthBar;
	private CShield m_shield;
	private float m_playerHealthRegen = 5.0f;
	

	public static synchronized CPlayer getInstance() {
		if (mInstance == null)
			mInstance = new CPlayer();

		return mInstance;
	}

	// CTOR
	public CPlayer() {
		// init base members
		super();
		TAG = "player";
		m_sprite = new CAnimatedSprite(8, 2, 4, 64.0f, 64.0f, 0.5f, true);
		m_nType = 0;
		pos.setX(10.0f);
		pos.setY(10.0f);
		m_healthBar = new CHealthBar(this);
		m_rect = new CRect();
		m_shield = new CShield();
	}

	public void Update(float dt) {
		
		// update the animated sprite 
		m_sprite.Update(dt);
		UpdateRectPosition();
		
		// check if we need to regen the players health 
		if( m_healthBar.getCurrentHealth() < m_healthBar.getMaxHealth() ) {
			m_healthBar.IncreaseHealth(m_playerHealthRegen*dt);
		}
		
		// update player health bar
		m_healthBar.Update(dt);
		
		// update the shield
		m_shield.Update(dt);
		
		if( m_bMoving )
		{
			if( m_fSpeed < MOVEMENT_SPEED )
			{
				m_fSpeed += MOVEMENT_INCREASE_RATE;
			}
			pos.setX(pos.getX() - (vel.getX()) * m_fSpeed * dt);
			pos.setY(pos.getY() - (vel.getY()) * m_fSpeed * dt);
		}
		else // we are not moving
		{
			
			if( m_fSpeed > 0.0f )
			{
				m_fSpeed -= MOVEMENT_REDUCTION_RATE;
				pos.setX(pos.getX() - (vel.getX()) * m_fSpeed * dt);
				pos.setY(pos.getY() - (vel.getY()) * m_fSpeed * dt);
			}
			else
			{
				vel.setX(0.0f);
				vel.setY(0.0f);
			}
		}
		
		CheckCollisions();
	}
	
	public void UpdateRectPosition()
	{
		m_rect.min.setX(pos.getX() - (m_sprite.getFrameWidth()*scale)*0.5f);
		m_rect.min.setY(pos.getY() - (m_sprite.getFrameHeight()*scale)*0.5f);
		m_rect.max.setX(pos.getX() + (m_sprite.getFrameWidth()*scale)*0.5f);
		m_rect.max.setY(pos.getY() + (m_sprite.getFrameHeight()*scale)*0.5f);
	}
	
	public void EnablePlayerMovement()
	{
		if( m_bMoving == false )
		{
			m_bMoving = true; 
			//m_fSpeed = MOVEMENT_SPEED;
		}
	}
	
	public void DisablePlayerMovement()
	{
		if( m_bMoving == true )
		{
			m_bMoving = false; 
		}
	}
	
	public void CheckCollisions()
	{
//		if( pos.getX() + m_sprite.getWidth()*0.5f >= m_screenWidth*m_fScreenClampFactor || pos.getX() - m_sprite.getWidth()*0.5f <= -m_screenWidth*m_fScreenClampFactor)
//		{
//			m_bAttachCameraX = true;
//			m_bAttachCamera = false;
//		}
//		if( pos.getY() + m_sprite.getHeight()*0.5f >= m_screenHeight*m_fScreenClampFactor || pos.getY() - m_sprite.getHeight()*0.5f <= -m_screenHeight*m_fScreenClampFactor)
//		{
//			m_bAttachCameraY = true;
//			m_bAttachCamera = false;
//		}
//		
//		if( pos.getX() + m_sprite.getWidth()*0.5f <= m_screenWidth*m_fScreenClampFactor && pos.getX() - m_sprite.getWidth()*0.5f >= -m_screenWidth*m_fScreenClampFactor &&
//				pos.getY() + m_sprite.getHeight()*0.5f <= m_screenHeight*m_fScreenClampFactor && pos.getY() - m_sprite.getHeight()*0.5f >= -m_screenHeight*m_fScreenClampFactor	)
//		{
//			m_bAttachCamera = true;
//		}
	}

	@Override
	public void Render(GL10 gl) {

		// render health bar
		gl.glPushMatrix();
		gl.glLoadIdentity();
		m_healthBar.RenderHealthBars(gl);
		m_shield.getDrainBar().RenderHealthBars(gl);
		
		gl.glPopMatrix();
		
		gl.glPushMatrix();
		
		//gl.glLoadIdentity();
		// translate the object
		//gl.glScalef(getScale(), getScale(), 1.0f);
		
		//gl.glTranslatef(0.0f, 0.0f, 0.0f);
		gl.glTranslatef(pos.getX(), pos.getY(), 0.0f);
		
		gl.glRotatef(rotation, 0.0f, 0.0f, 1.0f);
		//gl.glTranslatef(-(0.0f), -(0.0f), 0.0f);

		// set the textures
		gl.glEnable(GL10.GL_TEXTURE_2D);
		gl.glBindTexture(GL10.GL_TEXTURE_2D, m_sprite.getTextureID());
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
		// Point to our buffers
		gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, m_sprite.getTexBuffer());

		// draw
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, m_sprite.getVB());
		gl.glDrawElements(GL10.GL_TRIANGLES, m_sprite.getNumIndices(),
				GL10.GL_UNSIGNED_SHORT, m_sprite.getIB());

		
		// pop
		gl.glPopMatrix();
		
		// shield rendering 
		
		if(m_shield.isDraining())
		{
			gl.glPushMatrix();
			gl.glLoadIdentity();
			m_shield.RenderShield(gl);
			gl.glPopMatrix();
		}

	}
	
	private void InitHealthSystem(int w, int h)
	{
		// set up the health bar based on the screen
		m_healthBar.setScreen(w, h);
		Texture t = CAssetManager.GetInstance().getTexture(R.drawable.health_green);
		m_healthBar.getFrontSprite().setTexture(t, false);
				
		t = CAssetManager.GetInstance().getTexture(R.drawable.health_red);
		m_healthBar.getBackSprite().setTexture(t, true);
		
		m_healthBar.setPosX(m_screenWidth*0.5f);
		m_healthBar.setPosY(m_screenHeight - (m_healthBar.getBackSprite().height*0.5f));
		
		// init the shield bars 
		m_shield.InitDrainBar(w, h, m_healthBar);
	}

	// Accessors
	public int getType() {
		return m_nType;
	}
	public CRect getCollisionRect() { 
		return m_rect; 
	}
	public CAnimatedSprite getSprite() {
		return m_sprite;
	}
	public CHealthBar getHealthBar() { 
		return m_healthBar; 
	}
	public CShield getShield() { 
		return m_shield;
	}
		
	// Mutators
	public void setScreen(int w, int h)
	{
		m_screenWidth = w; 
		m_screenHeight = h;
		
		InitHealthSystem(w, h);	
	}
}
